#ifndef DATAMANAGER_H_INCLUDED
#define DATAMANAGER_H_INCLUDED

#include "DataExtention.h"

class pieARenderer;

/// //////////////
/// Data manager
/// //////////////
class CDataManager {
public:
	// Public data:
	enum { MaxEntries = 4096 };

public:
	// Public data structures:
	struct sDataHandleEntry {
		sDataHandleEntry( );
		explicit sDataHandleEntry( uint nextFreeIndex );

		//TODO make sure these bits are correct (reading/writing)
		uint m_uiNextFreeIndex	: 12;	///< Next free index bits
		uint m_uiCounter			: 15;	///< Counter bits
		uint m_uiActive			:  1;	///< Active flag bit
		uint m_uiEndOfList		:  1;	///< End of list flag bit
		uint m_uiType				;		///< Type bits

		handle m_hEntry;				///< Actual data entry
	};

private:
	// Private data:
	sDataHandleEntry	m_Entries[MaxEntries];	///< Data entries
	map<str,DATAH>		m_mapFilenameDatabase;	///< A place to register all red files.
	str					m_strRepoLocation;		///< Data repository HDD directory for direct relative loading

	int	m_iActiveEntryCount;		///< Active entry count
	uint	m_uiFirstFreeEntry;		///< First free entry

	list<IDataExtention*> m_listOfDataExtentions;

	// Private functions:
	CDataManager &operator = ( const CDataManager & );
	// C&D
	CDataManager( const CDataManager & );

public:
	// Primary functions:
	DATAH Add	( handle p, uint type );
	void 	Update( DATAH h, handle p );
	void 	Remove( DATAH h );
	void 	Reset	( );

	// Get functions:
	template< typename T > bool GetAs( DATAH h, T &out ) const;
	bool		Get( DATAH h, handle &out ) const;
	handle	Get( DATAH h ) const;
	DATAH		GetNextLike( DATAH h ) const;
	DATAH		GetPreviousLike( DATAH h ) const;
	DATAH		GetFirstOf( uint type ) const;
	int		GetCount() const;
	sDataHandleEntry* GetEntireRepository( int &count ) { count = MaxEntries; return m_Entries; }

	// General file load functions
	DATAH FileLoad( str filename, pieARenderer* context = NULL );
	void  IncludeDataExtention( IDataExtention* );
	void  RemoveDataExtention( str fileExtToMatch );

	 // C&D
	 CDataManager( str repo_dir = "" );
	~CDataManager( );
};

/// Get data resource as precise type
/**	@param h - identification handle
		@param out - the precise cast
		@returns if the cast is successful */
template< typename T > inline bool CDataManager::GetAs( DATAH h, T &out ) const {
	handle outAsVoid;
	const bool rv;

	rv		= Get( h, outAsVoid );
	//TODO research union_cast under mingw:
	out	= static_cast< T >( outAsVoid );

	return rv;
}




#endif // DATAMANAGER_H_INCLUDED
